package snmpstatistics;

import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.snmp4j.smi.IpAddress;

import features.SNMPClient;
import features.SNMPException;
import features.SNMPSession;
import features.SNMPValue;

public class SNMPStats {
	// .1.3.6.1.2.1.11
//	private final static String IN_PKTS_OID 				= ".1.3.6.1.2.1.11.1.0";
//	private final static String OUT_PKTS_OID 				= ".1.3.6.1.2.1.11.2.0";
//	private final static String IN_BAD_VERSIONS_OID			= ".1.3.6.1.2.1.11.3.0";
//	private final static String IN_BAD_COMMUNITY_NAMES_OID 	= ".1.3.6.1.2.1.11.4.0";
//	private final static String IN_BAD_COMMUNITY_USES_OID	= ".1.3.6.1.2.1.11.5.0";
//	private final static String IN_ADN_PARSE_ERRS_OID		= ".1.3.6.1.2.1.11.6.0";
//	private final static String IN_TOO_BIGS_OID				= ".1.3.6.1.2.1.11.8.0";
//	private final static String IN_NO_SUCH_NAMES_OID 		= ".1.3.6.1.2.1.11.9.0";
//	private final static String IN_BAD_VALUES_OID			= ".1.3.6.1.2.1.11.10.0";
//	private final static String IN_READ_ONLYS_OID			= ".1.3.6.1.2.1.11.11.0";
//	private final static String IN_GEN_ERRS_OID 			= ".1.3.6.1.2.1.11.12.0";
	
//	private final static String IN_TOTAL_REQ_VARS_OID 		= ".1.3.6.1.2.1.11.13.0";
//	private final static String IN_TOTAL_SET_VARS_OID 		= ".1.3.6.1.2.1.11.14.0";
//	private final static String IN_GET_REQUESTS_OID			= ".1.3.6.1.2.1.11.15.0";
//	private final static String IN_GET_NEXTS_OID 			= ".1.3.6.1.2.1.11.16.0";
//	private final static String IN_SET_REQUESTS_OID 		= ".1.3.6.1.2.1.11.17.0";
//	private final static String IN_GET_RESPONSES_OID		= ".1.3.6.1.2.1.11.18.0";
//	private final static String IN_TRAPS_OID 				= ".1.3.6.1.2.1.11.19.0";
//	private final static String OUT_TOO_BIGS_OID			= ".1.3.6.1.2.1.11.20.0";
//	private final static String OUT_NO_SUCH_NAMES_OID		= ".1.3.6.1.2.1.11.22.0";
//	private final static String OUT_BAD_VALUES_OID			= ".1.3.6.1.2.1.11.23.0";
//	private final static String OUT_GEN_ERRS_OID			= ".1.3.6.1.2.1.11.24.0";
//	private final static String OUT_GET_REQUESTS_OID		= ".1.3.6.1.2.1.11.25.0";
//	private final static String OUT_GET_NEXTS_OID			= ".1.3.6.1.2.1.11.26.0";
//	private final static String OUT_SET_REQUESTS_OID		= ".1.3.6.1.2.1.11.27.0";
//	private final static String OUT_GET_RESPONSES_OID 		= ".1.3.6.1.2.1.11.28.0";
//	private final static String OUT_TRAPS_OID				= ".1.3.6.1.2.1.11.29.0";
//	private final static String ENABLE_AUTHEN_TRAPS_OID		= ".1.3.6.1.2.1.11.30.0";

	
	private final static String IF_IN_UCAST_PKTS = ".1.3.6.1.2.1.2.2.1.11";
	private final static String IF_IN_NUCAST_PKTS = ".1.3.6.1.2.1.2.2.1.12"; 
	private final static String IF_OUT_UCAST_PKTS = ".1.3.6.1.2.1.2.2.1.17"; 
	private final static String IF_OUT_NUCAST_PKTS = ".1.3.6.1.2.1.2.2.1.18";
	private final static String IP_ADDR_TABLE = ".1.3.6.1.2.1.4.20";
	private int inPkts;
	private int outPkts;
	private int inBadVersions;
	private int inBadCommunityNames;
	private int inBadCommunityUses;
	private int inADNParseErrs;
	private int inTooBigs;
	private int inNoSuchNames;
	private int inBadValues;
	private int inReadOnlys;
	private int inGenErrs;
	private int inTotalReqVars;
	private int inTotalSetVars;
	private int inGetRequests;
	private int inGetNexts;
	private int inSetRequests;
	private int inGetResponses;
	private int inTraps;
	private int outTooBigs;
	private int outNoSuchNames;
	private int outBadValues;
	private int outGenErrs;
	private int outGetRequests;
	private int outGetNexts;
	private int outSetRequests;
	private int outGetResponses;
	private int outTraps;
	private int inUCastPkts;
	private int inNUCastPkts;
	private int outUCastPkts;
	private int outNUCastPkts;
	private String enableAuthenTraps;
	
	private SNMPSession session;
	
	public SNMPStats() {
	}
	private SNMPStats(SNMPSession session) {
		this.session = session;
	}

	public static SNMPStats fromSession(SNMPSession session)
			throws SNMPException {
		
		SNMPStats stats = new SNMPStats(session);
		
		List<SNMPValue> bulk = session.getBulk(".1.3.6.1.2.1.11");
		stats.setInPkts(bulk.get(0).toInt());
		stats.setOutPkts(bulk.get(1).toInt());
		stats.setInBadVersions(bulk.get(2).toInt());
		stats.setInBadCommunityNames(bulk.get(3).toInt());
		stats.setInBadCommunityUses(bulk.get(4).toInt());
		stats.setInADNParseErrs(bulk.get(5).toInt());
		stats.setInTooBigs(bulk.get(6).toInt());
		stats.setInNoSuchNames(bulk.get(7).toInt());
		stats.setInBadValues(bulk.get(8).toInt());
		stats.setInReadOnlys(bulk.get(9).toInt());
		stats.setInGenErrs(bulk.get(10).toInt());
		stats.setInTotalReqVars(bulk.get(11).toInt());
		stats.setInTotalSetVars(bulk.get(12).toInt());
		stats.setInGetRequests(bulk.get(13).toInt());
		stats.setInGetNexts(bulk.get(14).toInt());
		stats.setInSetRequests(bulk.get(15).toInt());
		stats.setInGetResponses(bulk.get(16).toInt());
		stats.setInTraps(bulk.get(17).toInt());
		stats.setOutTooBigs(bulk.get(18).toInt());
		stats.setOutNoSuchNames(bulk.get(19).toInt());
		stats.setOutBadValues(bulk.get(20).toInt());
		stats.setOutGenErrs(bulk.get(21).toInt());
		stats.setOutGetRequests(bulk.get(22).toInt());
		stats.setOutGetNexts(bulk.get(23).toInt());
		stats.setOutSetRequests(bulk.get(24).toInt());
		stats.setOutGetResponses(bulk.get(25).toInt());
		stats.setOutTraps(bulk.get(26).toInt());
		stats.setEnableAuthenTraps(EnableAuthenTraps.fromInt(bulk.get(27).toInt()).toString());

		stats.setInUCastPkts(getTotalPkts(session.getColumn(IF_IN_UCAST_PKTS)));
		stats.setInNUCastPkts(getTotalPkts(session.getColumn(IF_IN_NUCAST_PKTS)));
		stats.setOutUCastPkts(getTotalPkts(session.getColumn(IF_OUT_UCAST_PKTS)));
		stats.setOutNUCastPkts(getTotalPkts(session.getColumn(IF_OUT_NUCAST_PKTS)));
		
		return stats;
	}

	public static void main(String[] args) throws SNMPException {
		SNMPSession session = SNMPClient.startSession(SNMPClient.VERSION_2C);
		session.init(SNMPClient.DEFAULT_IP, SNMPClient.DEFAULT_PORT_STRING,
				SNMPClient.DEFAULT_COMMUNITY);

		SNMPStats.fromSession(session);
	}

	public int getInPkts() {
		return inPkts;
	}

	public void setInPkts(int inPkts) {
		this.inPkts = inPkts;
	}

	public int getOutPkts() {
		return outPkts;
	}

	public void setOutPkts(int outPkts) {
		this.outPkts = outPkts;
	}

	public int getInBadVersions() {
		return inBadVersions;
	}

	public void setInBadVersions(int inBadVersions) {
		this.inBadVersions = inBadVersions;
	}

	public int getInBadCommunityNames() {
		return inBadCommunityNames;
	}

	public void setInBadCommunityNames(int inBadCommunityNames) {
		this.inBadCommunityNames = inBadCommunityNames;
	}

	public int getInBadCommunityUses() {
		return inBadCommunityUses;
	}

	public void setInBadCommunityUses(int inBadCommunityUses) {
		this.inBadCommunityUses = inBadCommunityUses;
	}

	public int getInADNParseErrs() {
		return inADNParseErrs;
	}

	public void setInADNParseErrs(int inADNParseErrs) {
		this.inADNParseErrs = inADNParseErrs;
	}

	public int getInTooBigs() {
		return inTooBigs;
	}

	public void setInTooBigs(int inTooBigs) {
		this.inTooBigs = inTooBigs;
	}

	public int getInNoSuchNames() {
		return inNoSuchNames;
	}

	public void setInNoSuchNames(int inNoSuchNames) {
		this.inNoSuchNames = inNoSuchNames;
	}

	public int getInBadValues() {
		return inBadValues;
	}

	public void setInBadValues(int inBadValues) {
		this.inBadValues = inBadValues;
	}

	public int getInReadOnlys() {
		return inReadOnlys;
	}

	public void setInReadOnlys(int inReadOnlys) {
		this.inReadOnlys = inReadOnlys;
	}

	public int getInGenErrs() {
		return inGenErrs;
	}

	public void setInGenErrs(int inGenErrs) {
		this.inGenErrs = inGenErrs;
	}

	public int getInTotalReqVars() {
		return inTotalReqVars;
	}

	public void setInTotalReqVars(int inTotalReqVars) {
		this.inTotalReqVars = inTotalReqVars;
	}
	
	public int getInTotalSetVars() {
		return inTotalSetVars;
	}

	public void setInTotalSetVars(int inTotalSetVars) {
		this.inTotalSetVars = inTotalSetVars;
	}

	public int getInGetRequests() {
		return inGetRequests;
	}

	public void setInGetRequests(int inGetRequests) {
		this.inGetRequests = inGetRequests;
	}

	public int getInGetNexts() {
		return inGetNexts;
	}

	public void setInGetNexts(int inGetNexts) {
		this.inGetNexts = inGetNexts;
	}

	public int getInSetRequests() {
		return inSetRequests;
	}

	public void setInSetRequests(int inSetRequests) {
		this.inSetRequests = inSetRequests;
	}

	public int getInGetResponses() {
		return inGetResponses;
	}

	public void setInGetResponses(int inGetResponses) {
		this.inGetResponses = inGetResponses;
	}

	public int getInTraps() {
		return inTraps;
	}

	public void setInTraps(int inTraps) {
		this.inTraps = inTraps;
	}

	public int getOutTooBigs() {
		return outTooBigs;
	}

	public void setOutTooBigs(int outTooBigs) {
		this.outTooBigs = outTooBigs;
	}

	public int getOutNoSuchNames() {
		return outNoSuchNames;
	}

	public void setOutNoSuchNames(int outNoSuchNames) {
		this.outNoSuchNames = outNoSuchNames;
	}

	public int getOutBadValues() {
		return outBadValues;
	}

	public void setOutBadValues(int outBadValues) {
		this.outBadValues = outBadValues;
	}

	public int getOutGenErrs() {
		return outGenErrs;
	}

	public void setOutGenErrs(int outGenErrs) {
		this.outGenErrs = outGenErrs;
	}

	public int getOutGetRequests() {
		return outGetRequests;
	}

	public void setOutGetRequests(int outGetRequests) {
		this.outGetRequests = outGetRequests;
	}

	public int getOutGetNexts() {
		return outGetNexts;
	}

	public void setOutGetNexts(int outGetNexts) {
		this.outGetNexts = outGetNexts;
	}

	public int getOutSetRequests() {
		return outSetRequests;
	}

	public void setOutSetRequests(int outSetRequests) {
		this.outSetRequests = outSetRequests;
	}

	public int getOutGetResponses() {
		return outGetResponses;
	}

	public void setOutGetResponses(int outGetResponses) {
		this.outGetResponses = outGetResponses;
	}

	public int getOutTraps() {
		return outTraps;
	}

	public void setOutTraps(int outTraps) {
		this.outTraps = outTraps;
	}

	public String isEnableAuthenTraps() {
		return enableAuthenTraps;
	}

	public void setEnableAuthenTraps(String enableAuthenTraps) {
		this.enableAuthenTraps = enableAuthenTraps;
	}
	
	public int getInUCastPkts() {
		return inUCastPkts;
	}

	public void setInUCastPkts(int inUCastPkts) {
		this.inUCastPkts = inUCastPkts;
	}

	public int getInNUCastPkts() {
		return inNUCastPkts;
	}

	public void setInNUCastPkts(int inNUCastPkts) {
		this.inNUCastPkts = inNUCastPkts;
	}

	public int getOutUCastPkts() {
		return outUCastPkts;
	}

	public void setOutUCastPkts(int outUCastPkts) {
		this.outUCastPkts = outUCastPkts;
	}

	public int getOutNUCastPkts() {
		return outNUCastPkts;
	}

	public void setOutNUCastPkts(int outNUCastPkts) {
		this.outNUCastPkts = outNUCastPkts;
	}
	
	public float getRatePkts() {
		return (this.outPkts != 0) ? this.inPkts / this.outPkts : 0;
	}
	
	public float getRateTraps() {
		return (this.outTraps != 0) ? this.inTraps / this.outTraps : 0;
	}
	
	public float getRateTooBigs() {
		return (this.outTooBigs != 0) ? this.inTooBigs / this.outTooBigs : 0;
	}
	
	public float getRateBadValues() {
		return (this.outBadValues != 0) ? this.inBadValues / this.outBadValues : 0;
	}
	
	public float getRateGenErrs() {
		return (this.outGenErrs != 0) ? this.inGenErrs / this.outGenErrs : 0;
	}
	
	public float getRateGetRequests() {
		return (this.outGetRequests != 0) ? this.inGetRequests / this.outGetRequests : 0;
	}
	
	public float getRateGetNexts() {
		return (this.outGetNexts != 0) ? this.inGetNexts / this.outGetNexts : 0;
	}
	
	public float getRateNoSuchNames() {
		return (this.outNoSuchNames != 0) ? this.inNoSuchNames / this.outNoSuchNames : 0;
	}
	
	public float getRateSetRequests() {
		return (this.outSetRequests != 0) ? this.inSetRequests / this.outSetRequests : 0;
	}
	
	public float getRateGetResponses() {
		return (this.outGetResponses != 0) ? this.inGetResponses / this.outGetResponses : 0;
	}
	
	public float getInPDUErrorRate(){
		return (inPkts != 0) ? getInErrPkts()/inPkts : 0;
	}
	
	public float getOutPDUErrorRate(){
		return (outPkts != 0) ? getOutErrPkts()/outPkts : 0;
	}

	public int getInErrPkts() {
		return inADNParseErrs + inBadCommunityNames + inBadCommunityUses 
		+ inBadValues + inBadVersions + inGenErrs + inNoSuchNames;
	}

	public int getOutErrPkts() {
		return outBadValues + outGenErrs + outNoSuchNames;
	}

	public int getTotalInPkts(){
		return inUCastPkts + inNUCastPkts;
	}
	
	public int getTotalOutPkts(){
		return outUCastPkts + outNUCastPkts;
	}
	
	private static int getTotalPkts(List<SNMPValue> column) {
		int totalPkts = 0;
		for (SNMPValue value : column) {
			totalPkts += value.toInt();
		}
		return totalPkts;
	}
	
	private int getTotalInPackets(IpAddress address){
//		Hashtable<IpAddress, Integer> ipAddrTable = new Hashtable<IpAddress, Integer>();
//		
//		for (int i = 1; i <=3 ; i++) {
//			try {
//				Map<String, SNMPValue> tableRow = session.getTable(IP_ADDR_TABLE, i);
//			} catch (SNMPException e) {
//				e.printStackTrace();
//			}
//		}
		
		return 0;
	}
}
